/*
 * Copyright (C) 2013 Ted Kosan
 * 
 * This file is part of MathPiper Exercise.
 * 
 * Foobar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Foobar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mathpiper.ui.gui.android;

import java.util.HashMap;

import org.mathpiper.interpreters.EvaluationResponse;
import org.mathpiper.interpreters.Interpreter;
import org.mathpiper.interpreters.Interpreters;
import org.mathpiper.lisp.variables.GlobalVariable;

import android.app.Application;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;

public class ExerciseService extends Service implements Runnable,
		OnInitListener, OnUtteranceCompletedListener {
	private Thread casThread;
	private EvaluationResponse evaluationResponse;
	private Interpreter interpreter;
	private String inputText = null;
	private static ExerciseService singleton = null;
	private boolean run = true;
	private final IBinder mBinder = new LocalBinder();
	private static final String TAG = "ExerciseService";

	private TextToSpeech tts;
	static final int TTS_CHECK_CODE = 0;
	private HashMap<String, String> ttsParams;
	private HashMap<String, String> ttsParams_question;
	private OnUtteranceCompletedListener onUtteranceCompletedListener;

	@Override
	public void onInit(int initStatus) {
		if (initStatus == TextToSpeech.SUCCESS) {

			tts.setOnUtteranceCompletedListener(this);

		}
	}

	void speak(String text) {

		while (tts.isSpeaking()) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				Log.e(TAG, e.getMessage());
			}
		}

		tts.speak(text, TextToSpeech.QUEUE_FLUSH, ttsParams);

	}
	
	void speak(String text, String id) {

		while (tts.isSpeaking()) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				Log.e(TAG, e.getMessage());
			}
		}

		tts.speak(text, TextToSpeech.QUEUE_FLUSH, ttsParams_question);

	}

	public void onCreate() {
		super.onCreate();

		ttsParams = new HashMap<String, String>();

		ttsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "stringId");
		
		ttsParams_question = new HashMap<String, String>();

		ttsParams_question.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "question");

		tts = new TextToSpeech(this, this);

//		if (casThread == null) {
//			casThread = new Thread(new ThreadGroup("mathiper"), this,
//					"mathpiper", 50000);
//			casThread.start();
			interpreter = Interpreters.getSynchronousInterpreter();
			
			interpreter.evaluate("2+2;");
//		}
		singleton = this;
	}

	public void setOnUtteranceCompletedListener(
			OnUtteranceCompletedListener listener) {
		onUtteranceCompletedListener = listener;
	}
	
	public void removeOnUtteranceCompletedListener() {
		onUtteranceCompletedListener = null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return this.START_STICKY;
	}

	/** A client is binding to the service with bindService() */
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	/** Called when The service is no longer used and is being destroyed */
	@Override
	public void onDestroy() {
		tts.shutdown();
		casThread.interrupt();
		run = false;
	}

	public class LocalBinder extends Binder {
		ExerciseService getService() {
			// Return this instance of LocalService so clients can call public
			// methods
			return ExerciseService.this;
		}
	}

	public synchronized EvaluationResponse evaluate(String input) {

		input = input.replace("\\", "\\\\");
		input = input.replace("\"", "\\\"");

		inputText = "LoadScript(\"" + input + "\");";
		
		evaluationResponse = interpreter.evaluate(inputText);

		/*while (inputText != null) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
		}*/

		return evaluationResponse;
	}

	public void run() {

		while (run) {
			if (inputText == null) {
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					run = false;
				}
			} else {

				evaluationResponse = interpreter.evaluate(inputText);

				/*
				 * runOnUiThread(new Runnable() { public void run() {
				 * 
				 * String response;
				 * 
				 * if(evaluationResponse.isExceptionThrown()) { response =
				 * evaluationResponse.getException().getMessage(); } else {
				 * response = evaluationResponse.getResult(); }
				 * 
				 * } });
				 */

				inputText = null;
			}

		}
	}// end method

	public String getGlobalString(String variableName) {
		GlobalVariable variable = interpreter.getEnvironment().iGlobalState
				.get(variableName);

		if (variable == null) {
			return null;
		}

		String variableString = variable.toString();
		variableString = org.mathpiper.lisp.Utility
				.stripEndQuotesIfPresent(variableString);

		return variableString.toString();
	}

	public void onUtteranceCompleted(String utteranceId) {
		if (onUtteranceCompletedListener != null) {
			onUtteranceCompletedListener.onUtteranceCompleted(utteranceId);
		}
	}

}// end class.